﻿
/// <reference path="../BaseObject.js" />
/// <reference path="_namespace.js" />
/// <reference path="Point.js" />


/*****************************************************************************
Ajax library class definition. Kevin Robinson 2006.
Class: ajax.drawing.Viewport
/*****************************************************************************/

ajax.lang.addNamespace("ajax.drawing");

ajax.lang.imports("ajax.drawing.Point");

//-----------------------------------------------------------------------------
ajax.drawing.Viewport = function(x, y, width, height, viewingDistance, aspectRatio, zNear, zFar, graphicsScale)
{ 
    ajax.drawing.Viewport.superConstructor.call(this);
    x = typeof(x) == "undefined" ? 0 : x;
    y = typeof(y) == "undefined" ? 0 : y;
    this.topLeft            = new ajax.drawing.Point(x, y);
    
    this.setGraphicsScale(graphicsScale);    
    this.setWidth(width);
    this.setHeight(height);
    this.setViewingDistance(viewingDistance);

    this.aspectRatio        = aspectRatio;
    this.zNear              = zNear;
    this.zFar               = zFar;
}

//-----------------------------------------------------------------------------
ajax.lang.extend("ajax.drawing.Viewport", "ajax.BaseObject"); // Inherit
//-----------------------------------------------------------------------------
if ($getDesignMode())
    ajax.drawing.Viewport.prototype = ajax.BaseObject.prototype;



//-----------------------------------------------------------------------------
ajax.drawing.Viewport.prototype.computeCameraToScreen = function(cameraVerts)
{///<summary>Send in vertices transformed by World * View and this method will return an array of points with each vert Projected into the 2D Coords on the screen.</summary>
	// Create an array of verts to hold the result
	var screenVerts = new Array(cameraVerts.length);

	for (var i = 0; i < cameraVerts.length; i++)
	{
		// z must not be zero!!
		var z = cameraVerts[i].z;
        if (0 == z)
            z = 0.00001; // Some small float number
        
		var x = this.topLeft.x + parseInt((this.halfWidth  + (cameraVerts[i].x * this.viewingDistance) / z));
		var y = this.topLeft.y + parseInt((this.halfHeight + (-this.aspectRatio * cameraVerts[i].y * this.viewingDistance) / z));				
		
		screenVerts[i] = new ajax.drawing.Point(x, y);
	}

	return screenVerts;
}

//-----------------------------------------------------------------------------
ajax.drawing.Viewport.prototype.objectInsideFrustum = function(center, radius, matrix)
{///<param name="center" type="ajax.math.Vector3">The center of the object. Pass in a Zero Vector normally.</param>
 ///<param name="radius" type="float">The radius of the object.</param>
 ///<param name="matrix" type="ajax.math.Matrix">The World * View (camera space) matrix transform of the object.</param>
	// Transform the centre
	var cameraSpaceObj = matrix.transformVertex(center);

	// First we take care of the most trivial clipping - Z
	if ( 
		((cameraSpaceObj.z-radius) > this.zFar)
		||
		((cameraSpaceObj.z+radius) < this.zNear)
		)
		return false;


	// Now do X - changed to allow for graphic scaling
	//var xCompare = ((this.halfWidth/2) * cameraSpaceObj.z)/this.viewingDistance;
    var xCompare = (this.scaledWidth * cameraSpaceObj.z)/this.viewingDistance;
    
	if (
		((cameraSpaceObj.x-radius) > xCompare)
		||
		((cameraSpaceObj.x+radius) < -xCompare)
		)
		return false;

	// Y
	var yCompare = (this.aspectRatio * this.scaledHeight * cameraSpaceObj.z)/this.viewingDistance;

	if (
		((cameraSpaceObj.y-radius) > yCompare)
		||
		((cameraSpaceObj.y+radius) < -yCompare)
		)
		return false;

	return true;
}

//-----------------------------------------------------------------------------
ajax.drawing.Viewport.prototype.toString = function()
{
    return "ajax.drawing.Viewport";
}



//-----------------------------------------------------------------------------
ajax.drawing.Viewport.cast = function(obj)
{///<returns type="ajax.drawing.Viewport"/>
    return obj;    
}


// MS AJAX
ajax.drawing.Viewport.prototype.topLeft         = ajax.drawing.Point.prototype;
ajax.drawing.Viewport.prototype.width           = 0;
ajax.drawing.Viewport.prototype.halfWidth       = 0;
ajax.drawing.Viewport.prototype.height          = 0;
ajax.drawing.Viewport.prototype.halfHeight      = 0;
ajax.drawing.Viewport.prototype.scaledWidth     = 0;
ajax.drawing.Viewport.prototype.scaledHeight    = 0;
ajax.drawing.Viewport.prototype.viewingDistance = 0;
ajax.drawing.Viewport.prototype.aspectRatio     = 0;
ajax.drawing.Viewport.prototype.zNear           = 0;
ajax.drawing.Viewport.prototype.zFar            = 0;
ajax.drawing.Viewport.prototype.graphicsScale   = 1;


//-----------------------------------------------------------------------------
ajax.drawing.Viewport.prototype.setWidth = function(width)
{
    this.width          = width;
    this.halfWidth      = width / 2;
    this.scaledWidth    = this.halfWidth / this.graphicsScale;
}

//-----------------------------------------------------------------------------
ajax.drawing.Viewport.prototype.setHeight = function(height)
{
    this.height         = height;
    this.halfHeight     = height/2;
    this.scaledHeight   = this.halfHeight / this.graphicsScale;
}

//-----------------------------------------------------------------------------
ajax.drawing.Viewport.prototype.setViewingDistance = function(distance)
{
    this.viewingDistance = distance / this.graphicsScale;
}

//-----------------------------------------------------------------------------
ajax.drawing.Viewport.prototype.setGraphicsScale = function(scale)
{
    this.graphicsScale = scale;
    // Update all values that use the scale.
    this.setWidth(this.width);
    this.setHeight(this.height);
    this.setViewingDistance(this.viewingDistance);
}